﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace QDasConverter.Utils
{
    class PointUtil
    {
        private const short MARK_ANGLE_THRESHOLD = 4;
        private const short MARK_MOTOR_STOP = 2;
        private const short MARK_PREVAIL_INGTHRESHOLD = 1;

        /// <summary>
        /// 二进制数据转换为曲线中的点
        /// </summary>
        /// <param name="decodeByteArray">数据库CURVE表中CRV_BlobFormat字段的值（如果CRV_BlobFormat为2需要提前解压缩）</param>
        /// <param name="stride">提前计算好的步长，根据CURVE表中CRV_PointDuration计算</param>
        /// <returns></returns>
        public static List<CurvePoint> ConvertByteToPoints(byte[] decodeByteArray, float stride)
        {
            List<CurvePoint> pointList = new List<CurvePoint>();
            float pointDuration = 0.0f;
            for (int startIdx = 0; startIdx < decodeByteArray.Length; startIdx += 36)
            {
                CurvePoint point = ConvertByteToSinglePoint(decodeByteArray, startIdx, pointDuration);
                if (point != null)
                {
                    pointList.Add(point);
                }
                pointDuration += stride;
            }
            return pointList;
        }

        private static CurvePoint ConvertByteToSinglePoint(byte[] decodeByteArray, int startIdx, float pointDuration)
        {
            short index = BitConverter.ToInt16(decodeByteArray, startIdx);
            if (index == 0)
                return null;
            double torque = BitConverter.ToDouble(decodeByteArray, startIdx + 2);
            double angle = BitConverter.ToDouble(decodeByteArray, startIdx + 10);
            double torqueRate = BitConverter.ToDouble(decodeByteArray, startIdx + 18);
            double current = BitConverter.ToDouble(decodeByteArray, startIdx + 26);
            short maker = BitConverter.ToInt16(decodeByteArray, startIdx + 34);
            CurvePoint point = new CurvePoint();
            point.Index = index;
            point.Torque = torque;
            point.Angle = angle;
            point.TorqueRate = torqueRate;
            point.Current = current;
            point.Marker = ConvertMarkerInString(maker);
            point.PointDuration = pointDuration;
            return point;
        }

        private static double ConvertByteArrayToDouble(byte[] byteArray, int startIdx)
        {
            long result = 0L;
            for (int i = 0; i < 64; i += 8)
            {
                result |= (long)(byteArray[startIdx + i / 8] & 0xFF) << i;
            }
            return BitConverter.Int64BitsToDouble(result);
        }

        private static short ConvertByteArrayToShort(byte[] byteArray, int startIdx)
        {
            short shortResult = (short)((byteArray[startIdx] & 0xFF) | ((byteArray[startIdx + 1] & 0xFF) << 8));
            return shortResult;
        }

        private static string ConvertMarkerInString(short code)
        {
            string resultString = "";
            if (code <= 0)
            {
                return resultString;
            }
            else
            {
                if (code == MARK_ANGLE_THRESHOLD)
                {
                    resultString = "ANGLE THRESHOLD";
                }
                else if (code == MARK_MOTOR_STOP)
                {
                    resultString = "MOTOR STOP";
                }
                else if (code == MARK_PREVAIL_INGTHRESHOLD)
                {
                    resultString = "PREVAIL ING THRESHOLD";
                }
                return resultString;
            }
        }

    }



}
